package org.tlang.metaclass;

import org.tlang.ast.AST;
import org.tlang.ast.list.func.ArgumentList;
import org.tlang.ast.list.func.ParameterList;
import org.tlang.context.ValueTable;

public class TMethod extends TField implements TFunction {
    private final int localTableSize;
    private final AST functionBody;
    private final ParameterList parameterList;
    private final String tag; // for debug

    public TMethod(int nest, int index, int localTableSize, AST functionBody, ParameterList parameterList, String tag) {
        super(nest, index);
        this.localTableSize = localTableSize;
        this.functionBody = functionBody;
        this.parameterList = parameterList;
        this.tag = tag;
    }

    @Override
    public Object execute(ValueTable callerValueTable, ArgumentList arguments) {
        ValueTable localValueTable = new ValueTable(localTableSize, valueTable(), "method<" + tag + ">,local");
        parameterList.eval(localValueTable); // 向局部环境注入参数
        arguments.eval(localValueTable, callerValueTable, parameterList.offsets()); // 向局部环境注入参数值

        // 在局部环境中计算函数结果，计算完成后局部环境销毁
        Object result = functionBody.eval(localValueTable);
        if (result instanceof TReturn) {
            return ((TReturn) result).value();
        }

        return null;
    }
}
